home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Headers / g++ / Integer.h < prev    next >
C/C++ Source or Header  |  1995-02-06  |  27KB  |  1,098 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2.  
  3. /* 
  4. Copyright (C) 1988 Free Software Foundation
  5.     written by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Integer_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #pragma cplusplus
  24. #endif
  25. #define _Integer_h 1
  26.  
  27. #include <iostream.h>
  28.  
  29. struct IntRep                    // internal Integer representations
  30. {
  31.   unsigned short  len;          // current length
  32.   unsigned short  sz;           // allocated space (0 means static).
  33.   short           sgn;          // 1 means >= 0; 0 means < 0 
  34.   unsigned short  s[1];         // represented as ushort array starting here
  35. };
  36.  
  37. // True if REP is staticly (or manually) allocated,
  38. // and should not be deleted by an Integer destructor.
  39. #define STATIC_IntRep(rep) ((rep)->sz==0)
  40.  
  41. extern IntRep*  Ialloc(IntRep*, const unsigned short *, int, int, int);
  42. extern IntRep*  Icalloc(IntRep*, int);
  43. extern IntRep*  Icopy_ulong(IntRep*, unsigned long);
  44. extern IntRep*  Icopy_long(IntRep*, long);
  45. extern IntRep*  Icopy(IntRep*, const IntRep*);
  46. extern IntRep*  Iresize(IntRep*, int);
  47. extern IntRep*  add(const IntRep*, int, const IntRep*, int, IntRep*);
  48. extern IntRep*  add(const IntRep*, int, long, IntRep*);
  49. extern IntRep*  multiply(const IntRep*, const IntRep*, IntRep*);
  50. extern IntRep*  multiply(const IntRep*, long, IntRep*);
  51. extern IntRep*  lshift(const IntRep*, long, IntRep*);
  52. extern IntRep*  lshift(const IntRep*, const IntRep*, int, IntRep*);
  53. extern IntRep*  bitop(const IntRep*, const IntRep*, IntRep*, char);
  54. extern IntRep*  bitop(const IntRep*, long, IntRep*, char);
  55. extern IntRep*  power(const IntRep*, long, IntRep*);
  56. extern IntRep*  div(const IntRep*, const IntRep*, IntRep*);
  57. extern IntRep*  mod(const IntRep*, const IntRep*, IntRep*);
  58. extern IntRep*  div(const IntRep*, long, IntRep*);
  59. extern IntRep*  mod(const IntRep*, long, IntRep*);
  60. extern IntRep*  compl(const IntRep*, IntRep*);
  61. extern IntRep*  abs(const IntRep*, IntRep*);
  62. extern IntRep*  negate(const IntRep*, IntRep*);
  63. extern IntRep*  pow(const IntRep*, long);
  64. extern IntRep*  gcd(const IntRep*, const IntRep* y);
  65. extern int      compare(const IntRep*, const IntRep*);
  66. extern int      compare(const IntRep*, long);
  67. extern int      ucompare(const IntRep*, const IntRep*);
  68. extern int      ucompare(const IntRep*, long);
  69. extern char*    Itoa(const IntRep* x, int base = 10, int width = 0);
  70. extern char*    cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
  71.                         int showbase, int width, int align_right, 
  72.                         char fillchar, char Xcase, int showpos);
  73. extern IntRep*  atoIntRep(const char* s, int base = 10);
  74. extern long     Itolong(const IntRep*);
  75. extern int      Iislong(const IntRep*);
  76. extern long     lg(const IntRep*);
  77.  
  78. extern IntRep _ZeroRep, _OneRep, _MinusOneRep;
  79.  
  80. class Integer
  81. {
  82. protected:
  83.   IntRep*         rep;
  84. public:
  85.                   Integer();
  86.                   Integer(int);
  87.                   Integer(long);
  88.                   Integer(unsigned long);
  89.                   Integer(IntRep*);
  90.                   Integer(const Integer&);
  91.  
  92.                   ~Integer();
  93.  
  94.   void            operator =  (const Integer&);
  95.   void            operator =  (long);
  96.  
  97. // unary operations to self
  98.  
  99.   void            operator ++ ();
  100.   void            operator -- ();
  101.   void            negate();          // negate in-place
  102.   void            abs();             // absolute-value in-place
  103.   void            complement();      // bitwise complement in-place
  104.  
  105. // assignment-based operations
  106.  
  107.   void            operator += (const Integer&);
  108.   void            operator -= (const Integer&);
  109.   void            operator *= (const Integer&);
  110.   void            operator /= (const Integer&);
  111.   void            operator %= (const Integer&);
  112.   void            operator <<=(const Integer&);
  113.   void            operator >>=(const Integer&);
  114.   void            operator &= (const Integer&);
  115.   void            operator |= (const Integer&);
  116.   void            operator ^= (const Integer&);
  117.  
  118.   void            operator += (long);
  119.   void            operator -= (long);
  120.   void            operator *= (long);
  121.   void            operator /= (long);
  122.   void            operator %= (long);
  123.   void            operator <<=(long);
  124.   void            operator >>=(long);
  125.   void            operator &= (long);
  126.   void            operator |= (long);
  127.   void            operator ^= (long);
  128.  
  129. // (constructive binary operations are inlined below)
  130.  
  131. #ifdef __GNUG__
  132.   friend Integer operator <? (const Integer& x, const Integer& y); // min
  133.   friend Integer operator >? (const Integer& x, const Integer& y); // max
  134. #endif
  135.  
  136. // builtin Integer functions that must be friends
  137.  
  138.   friend long     lg (const Integer&); // floor log base 2 of abs(x)
  139.   friend double   ratio(const Integer& x, const Integer& y);
  140.                   // return x/y as a double
  141.  
  142.   friend Integer  gcd(const Integer&, const Integer&);
  143.   friend int      even(const Integer&); // true if even
  144.   friend int      odd(const Integer&); // true if odd
  145.   friend int      sign(const Integer&); // returns -1, 0, +1
  146.  
  147.   friend void     (setbit)(Integer& x, long b);   // set b'th bit of x
  148.   friend void     clearbit(Integer& x, long b); // clear b'th bit
  149.   friend int      testbit(const Integer& x, long b);  // return b'th bit
  150.  
  151. // procedural versions of operators
  152.  
  153.   friend void     abs(const Integer& x, Integer& dest);
  154.   friend void     negate(const Integer& x, Integer& dest);
  155.   friend void     complement(const Integer& x, Integer& dest);
  156.  
  157.   friend int      compare(const Integer&, const Integer&);  
  158.   friend int      ucompare(const Integer&, const Integer&); 
  159.   friend void     add(const Integer& x, const Integer& y, Integer& dest);
  160.   friend void     sub(const Integer& x, const Integer& y, Integer& dest);
  161.   friend void     mul(const Integer& x, const Integer& y, Integer& dest);
  162.   friend void     div(const Integer& x, const Integer& y, Integer& dest);
  163.   friend void     mod(const Integer& x, const Integer& y, Integer& dest);
  164.   friend void     divide(const Integer& x, const Integer& y, 
  165.                          Integer& q, Integer& r);
  166.   friend void     and(const Integer& x, const Integer& y, Integer& dest);
  167.   friend void     or(const Integer& x, const Integer& y, Integer& dest);
  168.   friend void     xor(const Integer& x, const Integer& y, Integer& dest);
  169.   friend void     lshift(const Integer& x, const Integer& y, Integer& dest);
  170.   friend void     rshift(const Integer& x, const Integer& y, Integer& dest);
  171.   friend void     pow(const Integer& x, const Integer& y, Integer& dest);
  172.  
  173.   friend int      compare(const Integer&, long);  
  174.   friend int      ucompare(const Integer&, long); 
  175.   friend void     add(const Integer& x, long y, Integer& dest);
  176.   friend void     sub(const Integer& x, long y, Integer& dest);
  177.   friend void     mul(const Integer& x, long y, Integer& dest);
  178.   friend void     div(const Integer& x, long y, Integer& dest);
  179.   friend void     mod(const Integer& x, long y, Integer& dest);
  180.   friend void     divide(const Integer& x, long y, Integer& q, long& r);
  181.   friend void     and(const Integer& x, long y, Integer& dest);
  182.   friend void     or(const Integer& x, long y, Integer& dest);
  183.   friend void     xor(const Integer& x, long y, Integer& dest);
  184.   friend void     lshift(const Integer& x, long y, Integer& dest);
  185.   friend void     rshift(const Integer& x, long y, Integer& dest);
  186.   friend void     pow(const Integer& x, long y, Integer& dest);
  187.  
  188.   friend int      compare(long, const Integer&);  
  189.   friend int      ucompare(long, const Integer&); 
  190.   friend void     add(long x, const Integer& y, Integer& dest);
  191.   friend void     sub(long x, const Integer& y, Integer& dest);
  192.   friend void     mul(long x, const Integer& y, Integer& dest);
  193.   friend void     and(long x, const Integer& y, Integer& dest);
  194.   friend void     or(long x, const Integer& y, Integer& dest);
  195.   friend void     xor(long x, const Integer& y, Integer& dest);
  196.  
  197. // coercion & conversion
  198.  
  199.   int             fits_in_long() const { return Iislong(rep); }
  200.   int             fits_in_double() const;
  201.  
  202.   long          as_long() const { return Itolong(rep); }
  203.   double      as_double() const;
  204.  
  205.   friend char*    Itoa(const Integer& x, int base = 10, int width = 0);
  206.   friend Integer  atoI(const char* s, int base = 10);
  207.   void          printon(ostream& s, int base = 10, int width = 0) const;
  208.   
  209.   friend istream& operator >> (istream& s, Integer& y);
  210.   friend ostream& operator << (ostream& s, const Integer& y);
  211.  
  212. // error detection
  213.  
  214.   int             initialized() const;
  215.   void   error(const char* msg) const;
  216.   int             OK() const;  
  217. };
  218.  
  219.  
  220. //  (These are declared inline)
  221.  
  222.   int      operator == (const Integer&, const Integer&);
  223.   int      operator == (const Integer&, long);
  224.   int      operator != (const Integer&, const Integer&);
  225.   int      operator != (const Integer&, long);
  226.   int      operator <  (const Integer&, const Integer&);
  227.   int      operator <  (const Integer&, long);
  228.   int      operator <= (const Integer&, const Integer&);
  229.   int      operator <= (const Integer&, long);
  230.   int      operator >  (const Integer&, const Integer&);
  231.   int      operator >  (const Integer&, long);
  232.   int      operator >= (const Integer&, const Integer&);
  233.   int      operator >= (const Integer&, long);
  234.   Integer  operator -  (const Integer&);
  235.   Integer  operator ~  (const Integer&);
  236.   Integer  operator +  (const Integer&, const Integer&);
  237.   Integer  operator +  (const Integer&, long);
  238.   Integer  operator +  (long, const Integer&);
  239.   Integer  operator -  (const Integer&, const Integer&);
  240.   Integer  operator -  (const Integer&, long);
  241.   Integer  operator -  (long, const Integer&);
  242.   Integer  operator *  (const Integer&, const Integer&);
  243.   Integer  operator *  (const Integer&, long);
  244.   Integer  operator *  (long, const Integer&);
  245.   Integer  operator /  (const Integer&, const Integer&);
  246.   Integer  operator /  (const Integer&, long);
  247.   Integer  operator %  (const Integer&, const Integer&);
  248.   Integer  operator %  (const Integer&, long);
  249.   Integer  operator << (const Integer&, const Integer&);
  250.   Integer  operator << (const Integer&, long);
  251.   Integer  operator >> (const Integer&, const Integer&);
  252.   Integer  operator >> (const Integer&, long);
  253.   Integer  operator &  (const Integer&, const Integer&);
  254.   Integer  operator &  (const Integer&, long);
  255.   Integer  operator &  (long, const Integer&);
  256.   Integer  operator |  (const Integer&, const Integer&);
  257.   Integer  operator |  (const Integer&, long);
  258.   Integer  operator |  (long, const Integer&);
  259.   Integer  operator ^  (const Integer&, const Integer&);
  260.   Integer  operator ^  (const Integer&, long);
  261.   Integer  operator ^  (long, const Integer&);
  262.  
  263.   Integer  abs(const Integer&); // absolute value
  264.   Integer  sqr(const Integer&); // square
  265.  
  266.   Integer  pow(const Integer& x, const Integer& y);
  267.   Integer  pow(const Integer& x, long y);
  268.   Integer  Ipow(long x, long y); // x to the y as Integer 
  269.  
  270.  
  271. extern char*    dec(const Integer& x, int width = 0);
  272. extern char*    oct(const Integer& x, int width = 0);
  273. extern char*    hex(const Integer& x, int width = 0);
  274. extern Integer  sqrt(const Integer&); // floor of square root
  275. extern Integer  lcm(const Integer& x, const Integer& y); // least common mult
  276.  
  277.  
  278. typedef Integer IntTmp; // for backward compatibility
  279.  
  280. inline Integer::Integer() :rep(&_ZeroRep) {}
  281.  
  282. inline Integer::Integer(IntRep* r) :rep(r) {}
  283.  
  284. inline Integer::Integer(int y) :rep(Icopy_long(0, (long)y)) {}
  285.  
  286. inline Integer::Integer(long y) :rep(Icopy_long(0, y)) {}
  287.  
  288. inline Integer::Integer(unsigned long y) :rep(Icopy_ulong(0, y)) {}
  289.  
  290. inline Integer::Integer(const Integer&  y) :rep(Icopy(0, y.rep)) {}
  291.  
  292. inline Integer::~Integer() { if (rep && !STATIC_IntRep(rep)) delete rep; }
  293.  
  294. inline void  Integer::operator = (const Integer&  y)
  295. {
  296.   rep = Icopy(rep, y.rep);
  297. }
  298.  
  299. inline void Integer::operator = (long y)
  300. {
  301.   rep = Icopy_long(rep, y); 
  302. }
  303.  
  304. inline int Integer::initialized() const
  305. {
  306.   return rep != 0;
  307. }
  308.  
  309. // procedural versions
  310.  
  311. inline int compare(const Integer& x, const Integer& y)
  312. {
  313.   return compare(x.rep, y.rep);
  314. }
  315.  
  316. inline int ucompare(const Integer& x, const Integer& y)
  317. {
  318.   return ucompare(x.rep, y.rep);
  319. }
  320.  
  321. inline int compare(const Integer& x, long y)
  322. {
  323.   return compare(x.rep, y);
  324. }
  325.  
  326. inline int ucompare(const Integer& x, long y)
  327. {
  328.   return ucompare(x.rep, y);
  329. }
  330.  
  331. inline int compare(long x, const Integer& y)
  332. {
  333.   return -compare(y.rep, x);
  334. }
  335.  
  336. inline int ucompare(long x, const Integer& y)
  337. {
  338.   return -ucompare(y.rep, x);
  339. }
  340.  
  341. inline void  add(const Integer& x, const Integer& y, Integer& dest)
  342. {
  343.   dest.rep = add(x.rep, 0, y.rep, 0, dest.rep);
  344. }
  345.  
  346. inline void  sub(const Integer& x, const Integer& y, Integer& dest)
  347. {
  348.   dest.rep = add(x.rep, 0, y.rep, 1, dest.rep);
  349. }
  350.  
  351. inline void  mul(const Integer& x, const Integer& y, Integer& dest)
  352. {
  353.   dest.rep = multiply(x.rep, y.rep, dest.rep);
  354. }
  355.  
  356. inline void  div(const Integer& x, const Integer& y, Integer& dest)
  357. {
  358.   dest.rep = div(x.rep, y.rep, dest.rep);
  359. }
  360.  
  361. inline void  mod(const Integer& x, const Integer& y, Integer& dest)
  362. {
  363.   dest.rep = mod(x.rep, y.rep, dest.rep);
  364. }
  365.  
  366. inline void  and(const Integer& x, const Integer& y, Integer& dest)
  367. {
  368.   dest.rep = bitop(x.rep, y.rep, dest.rep, '&');
  369. }
  370.  
  371. inline void  or(const Integer& x, const Integer& y, Integer& dest)
  372. {
  373.   dest.rep = bitop(x.rep, y.rep, dest.rep, '|');
  374. }
  375.  
  376. inline void  xor(const Integer& x, const Integer& y, Integer& dest)
  377. {
  378.   dest.rep = bitop(x.rep, y.rep, dest.rep, '^');
  379. }
  380.  
  381. inline void  lshift(const Integer& x, const Integer& y, Integer& dest)
  382. {
  383.   dest.rep = lshift(x.rep, y.rep, 0, dest.rep);
  384. }
  385.  
  386. inline void  rshift(const Integer& x, const Integer& y, Integer& dest)
  387. {
  388.   dest.rep = lshift(x.rep, y.rep, 1, dest.rep);
  389. }
  390.  
  391. inline void  pow(const Integer& x, const Integer& y, Integer& dest)
  392. {
  393.   dest.rep = power(x.rep, Itolong(y.rep), dest.rep); // not incorrect
  394. }
  395.  
  396. inline void  add(const Integer& x, long y, Integer& dest)
  397. {
  398.   dest.rep = add(x.rep, 0, y, dest.rep);
  399. }
  400.  
  401. inline void  sub(const Integer& x, long y, Integer& dest)
  402. {
  403.   dest.rep = add(x.rep, 0, -y, dest.rep);
  404. }
  405.  
  406. inline void  mul(const Integer& x, long y, Integer& dest)
  407. {
  408.   dest.rep = multiply(x.rep, y, dest.rep);
  409. }
  410.  
  411. inline void  div(const Integer& x, long y, Integer& dest)
  412. {
  413.   dest.rep = div(x.rep, y, dest.rep);
  414. }
  415.  
  416. inline void  mod(const Integer& x, long y, Integer& dest)
  417. {
  418.   dest.rep = mod(x.rep, y, dest.rep);
  419. }
  420.  
  421. inline void  and(const Integer& x, long y, Integer& dest)
  422. {
  423.   dest.rep = bitop(x.rep, y, dest.rep, '&');
  424. }
  425.  
  426. inline void  or(const Integer& x, long y, Integer& dest)
  427. {
  428.   dest.rep = bitop(x.rep, y, dest.rep, '|');
  429. }
  430.  
  431. inline void  xor(const Integer& x, long y, Integer& dest)
  432. {
  433.   dest.rep = bitop(x.rep, y, dest.rep, '^');
  434. }
  435.  
  436. inline void  lshift(const Integer& x, long y, Integer& dest)
  437. {
  438.   dest.rep = lshift(x.rep, y, dest.rep);
  439. }
  440.  
  441. inline void  rshift(const Integer& x, long y, Integer& dest)
  442. {
  443.   dest.rep = lshift(x.rep, -y, dest.rep);
  444. }
  445.  
  446. inline void  pow(const Integer& x, long y, Integer& dest)
  447. {
  448.   dest.rep = power(x.rep, y, dest.rep);
  449. }
  450.  
  451. inline void abs(const Integer& x, Integer& dest)
  452. {
  453.   dest.rep = abs(x.rep, dest.rep);
  454. }
  455.  
  456. inline void negate(const Integer& x, Integer& dest)
  457. {
  458.   dest.rep = negate(x.rep, dest.rep);
  459. }
  460.  
  461. inline void complement(const Integer& x, Integer& dest)
  462. {
  463.   dest.rep = compl(x.rep, dest.rep);
  464. }
  465.  
  466. inline void  add(long x, const Integer& y, Integer& dest)
  467. {
  468.   dest.rep = add(y.rep, 0, x, dest.rep);
  469. }
  470.  
  471. inline void  sub(long x, const Integer& y, Integer& dest)
  472. {
  473.   dest.rep = add(y.rep, 1, x, dest.rep);
  474. }
  475.  
  476. inline void  mul(long x, const Integer& y, Integer& dest)
  477. {
  478.   dest.rep = multiply(y.rep, x, dest.rep);
  479. }
  480.  
  481. inline void  and(long x, const Integer& y, Integer& dest)
  482. {
  483.   dest.rep = bitop(y.rep, x, dest.rep, '&');
  484. }
  485.  
  486. inline void  or(long x, const Integer& y, Integer& dest)
  487. {
  488.   dest.rep = bitop(y.rep, x, dest.rep, '|');
  489. }
  490.  
  491. inline void  xor(long x, const Integer& y, Integer& dest)
  492. {
  493.   dest.rep = bitop(y.rep, x, dest.rep, '^');
  494. }
  495.  
  496.  
  497. // operator versions
  498.  
  499. inline int operator == (const Integer&  x, const Integer&  y)
  500. {
  501.   return compare(x, y) == 0; 
  502. }
  503.  
  504. inline int operator == (const Integer&  x, long y)
  505. {
  506.   return compare(x, y) == 0; 
  507. }
  508.  
  509. inline int operator != (const Integer&  x, const Integer&  y)
  510. {
  511.   return compare(x, y) != 0; 
  512. }
  513.  
  514. inline int operator != (const Integer&  x, long y)
  515. {
  516.   return compare(x, y) != 0; 
  517. }
  518.  
  519. inline int operator <  (const Integer&  x, const Integer&  y)
  520. {
  521.   return compare(x, y) <  0; 
  522. }
  523.  
  524. inline int operator <  (const Integer&  x, long y)
  525. {
  526.   return compare(x, y) <  0; 
  527. }
  528.  
  529. inline int operator <= (const Integer&  x, const Integer&  y)
  530. {
  531.   return compare(x, y) <= 0; 
  532. }
  533.  
  534. inline int operator <= (const Integer&  x, long y)
  535. {
  536.   return compare(x, y) <= 0; 
  537. }
  538.  
  539. inline int operator >  (const Integer&  x, const Integer&  y)
  540. {
  541.   return compare(x, y) >  0; 
  542. }
  543.  
  544. inline int operator >  (const Integer&  x, long y)
  545. {
  546.   return compare(x, y) >  0; 
  547. }
  548.  
  549. inline int operator >= (const Integer&  x, const Integer&  y)
  550. {
  551.   return compare(x, y) >= 0; 
  552. }
  553.  
  554. inline int operator >= (const Integer&  x, long y)
  555. {
  556.   return compare(x, y) >= 0; 
  557. }
  558.  
  559.  
  560. inline void  Integer::operator += (const Integer& y)
  561. {
  562.   add(*this, y, *this);
  563. }
  564.  
  565. inline void  Integer::operator += (long y)
  566. {
  567.   add(*this, y, *this);
  568. }
  569.  
  570. inline void Integer::operator ++ ()
  571. {
  572.   add(*this, 1, *this);
  573. }
  574.  
  575.  
  576. inline void  Integer::operator -= (const Integer& y)
  577. {
  578.   sub(*this, y, *this);
  579. }
  580.  
  581. inline void  Integer::operator -= (long y)
  582. {
  583.   sub(*this, y, *this);
  584. }
  585.  
  586. inline void Integer::operator -- ()
  587. {
  588.   add(*this, -1, *this);
  589. }
  590.  
  591.  
  592.  
  593. inline void Integer::operator *= (const Integer& y)
  594. {
  595.   mul(*this, y, *this);
  596. }
  597.  
  598. inline void Integer::operator *= (long y)
  599. {
  600.   mul(*this, y, *this);
  601. }
  602.  
  603.  
  604. inline void  Integer::operator &= (const Integer& y)
  605. {
  606.   and(*this, y, *this);
  607. }
  608.  
  609. inline void  Integer::operator &= (long y)
  610. {
  611.   and(*this, y, *this);
  612. }
  613.  
  614. inline void  Integer::operator |= (const Integer& y)
  615. {
  616.   or(*this, y, *this);
  617. }
  618.  
  619. inline void  Integer::operator |= (long y)
  620. {
  621.   or(*this, y, *this);
  622. }
  623.  
  624.  
  625. inline void  Integer::operator ^= (const Integer& y)
  626. {
  627.   xor(*this, y, *this);
  628. }
  629.  
  630. inline void  Integer::operator ^= (long y)
  631. {
  632.   xor(*this, y, *this);
  633. }
  634.  
  635.  
  636.  
  637. inline void Integer::operator /= (const Integer& y)
  638. {
  639.   div(*this, y, *this);
  640. }
  641.  
  642. inline void Integer::operator /= (long y)
  643. {
  644.   div(*this, y, *this);
  645. }
  646.  
  647.  
  648. inline void Integer::operator <<= (const Integer&  y)
  649. {
  650.   lshift(*this, y, *this);
  651. }
  652.  
  653. inline void Integer::operator <<= (long  y)
  654. {
  655.   lshift(*this, y, *this);
  656. }
  657.  
  658.  
  659. inline void Integer::operator >>= (const Integer&  y)
  660. {
  661.   rshift(*this, y, *this);
  662. }
  663.  
  664. inline void  Integer::operator >>= (long y)
  665. {
  666.   rshift(*this, y, *this);
  667. }
  668.  
  669. #ifdef __GNUG__
  670. inline Integer operator <? (const Integer& x, const Integer& y)
  671. {
  672.   return (compare(x.rep, y.rep) <= 0) ? x : y;
  673. }
  674.  
  675. inline Integer operator >? (const Integer& x, const Integer& y)
  676. {
  677.   return (compare(x.rep, y.rep) >= 0)?  x : y;
  678. }
  679. #endif
  680.  
  681.  
  682. inline void Integer::abs()
  683. {
  684.   ::abs(*this, *this);
  685. }
  686.  
  687. inline void Integer::negate()
  688. {
  689.   ::negate(*this, *this);
  690. }
  691.  
  692.  
  693. inline void Integer::complement()
  694. {
  695.   ::complement(*this, *this);
  696. }
  697.  
  698.  
  699. inline int sign(const Integer& x)
  700. {
  701.   return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
  702. }
  703.  
  704. inline int even(const Integer& y)
  705. {
  706.   return y.rep->len == 0 || !(y.rep->s[0] & 1);
  707. }
  708.  
  709. inline int odd(const Integer& y)
  710. {
  711.   return y.rep->len > 0 && (y.rep->s[0] & 1);
  712. }
  713.  
  714. inline char* Itoa(const Integer& y, int base, int width)
  715. {
  716.   return Itoa(y.rep, base, width);
  717. }
  718.  
  719.  
  720.  
  721. inline long lg(const Integer& x) 
  722. {
  723.   return lg(x.rep);
  724. }
  725.  
  726. // constructive operations 
  727.  
  728. #if defined(__GNUG__) && !defined(NO_NRV)
  729.  
  730. inline Integer  operator +  (const Integer& x, const Integer& y) return r
  731. {
  732.   add(x, y, r);
  733. }
  734.  
  735. inline Integer  operator +  (const Integer& x, long y) return r
  736. {
  737.   add(x, y, r);
  738. }
  739.  
  740. inline Integer  operator +  (long  x, const Integer& y) return r
  741. {
  742.   add(x, y, r);
  743. }
  744.  
  745. inline Integer  operator -  (const Integer& x, const Integer& y) return r
  746. {
  747.   sub(x, y, r);
  748. }
  749.  
  750. inline Integer  operator -  (const Integer& x, long y) return r
  751. {
  752.   sub(x, y, r);
  753. }
  754.  
  755. inline Integer  operator -  (long  x, const Integer& y) return r
  756. {
  757.   sub(x, y, r);
  758. }
  759.  
  760. inline Integer  operator *  (const Integer& x, const Integer& y) return r
  761. {
  762.   mul(x, y, r);
  763. }
  764.  
  765. inline Integer  operator *  (const Integer& x, long y) return r
  766. {
  767.   mul(x, y, r);
  768. }
  769.  
  770. inline Integer  operator *  (long  x, const Integer& y) return r
  771. {
  772.   mul(x, y, r);
  773. }
  774.  
  775. inline Integer sqr(const Integer& x) return r
  776. {
  777.   mul(x, x, r);
  778. }
  779.  
  780. inline Integer  operator &  (const Integer& x, const Integer& y) return r
  781. {
  782.   and(x, y, r);
  783. }
  784.  
  785. inline Integer  operator &  (const Integer& x, long y) return r
  786. {
  787.   and(x, y, r);
  788. }
  789.  
  790. inline Integer  operator &  (long  x, const Integer& y) return r
  791. {
  792.   and(x, y, r);
  793. }
  794.  
  795. inline Integer  operator |  (const Integer& x, const Integer& y) return r
  796. {
  797.   or(x, y, r);
  798. }
  799.  
  800. inline Integer  operator |  (const Integer& x, long y) return r
  801. {
  802.   or(x, y, r);
  803. }
  804.  
  805. inline Integer  operator |  (long  x, const Integer& y) return r
  806. {
  807.   or(x, y, r);
  808. }
  809.  
  810. inline Integer  operator ^  (const Integer& x, const Integer& y) return r
  811. {
  812.   xor(x, y, r);
  813. }
  814.  
  815. inline Integer  operator ^  (const Integer& x, long y) return r
  816. {
  817.   xor(x, y, r);
  818. }
  819.  
  820. inline Integer  operator ^  (long  x, const Integer& y) return r
  821. {
  822.   xor(x, y, r);
  823. }
  824.  
  825. inline Integer  operator /  (const Integer& x, const Integer& y) return r
  826. {
  827.   div(x, y, r);
  828. }
  829.  
  830. inline Integer operator /  (const Integer& x, long y) return r
  831. {
  832.   div(x, y, r);
  833. }
  834.  
  835. inline Integer operator %  (const Integer& x, const Integer& y) return r
  836. {
  837.   mod(x, y, r);
  838. }
  839.  
  840. inline Integer operator %  (const Integer& x, long y) return r
  841. {
  842.   mod(x, y, r);
  843. }
  844.  
  845. inline Integer operator <<  (const Integer& x, const Integer& y) return r
  846. {
  847.   lshift(x, y, r);
  848. }
  849.  
  850. inline Integer operator <<  (const Integer& x, long y) return r
  851. {
  852.   lshift(x, y, r);
  853. }
  854.  
  855. inline Integer operator >>  (const Integer& x, const Integer& y) return r;
  856. {
  857.   rshift(x, y, r);
  858. }
  859.  
  860. inline Integer operator >>  (const Integer& x, long y) return r
  861. {
  862.   rshift(x, y, r);
  863. }
  864.  
  865. inline Integer pow(const Integer& x, long y) return r
  866. {
  867.   pow(x, y, r);
  868. }
  869.  
  870. inline Integer Ipow(long x, long y) return r(x)
  871. {
  872.   pow(r, y, r);
  873. }
  874.  
  875. inline Integer pow(const Integer& x, const Integer& y) return r
  876. {
  877.   pow(x, y, r);
  878. }
  879.  
  880.  
  881.  
  882. inline Integer abs(const Integer& x) return r
  883. {
  884.   abs(x, r);
  885. }
  886.  
  887. inline Integer operator - (const Integer& x) return r
  888. {
  889.   negate(x, r);
  890. }
  891.  
  892. inline Integer operator ~ (const Integer& x) return r
  893. {
  894.   complement(x, r);
  895. }
  896.  
  897. inline Integer  atoI(const char* s, int base) return r
  898. {
  899.   r.rep = atoIntRep(s, base);
  900. }
  901.  
  902. inline Integer  gcd(const Integer& x, const Integer& y) return r
  903. {
  904.   r.rep = gcd(x.rep, y.rep);
  905. }
  906.  
  907. #else /* NO_NRV */
  908.  
  909. inline Integer  operator +  (const Integer& x, const Integer& y) 
  910. {
  911.   Integer r; add(x, y, r); return r;
  912. }
  913.  
  914. inline Integer  operator +  (const Integer& x, long y) 
  915. {
  916.   Integer r; add(x, y, r); return r;
  917. }
  918.  
  919. inline Integer  operator +  (long  x, const Integer& y) 
  920. {
  921.   Integer r; add(x, y, r); return r;
  922. }
  923.  
  924. inline Integer  operator -  (const Integer& x, const Integer& y) 
  925. {
  926.   Integer r; sub(x, y, r); return r;
  927. }
  928.  
  929. inline Integer  operator -  (const Integer& x, long y) 
  930. {
  931.   Integer r; sub(x, y, r); return r;
  932. }
  933.  
  934. inline Integer  operator -  (long  x, const Integer& y) 
  935. {
  936.   Integer r; sub(x, y, r); return r;
  937. }
  938.  
  939. inline Integer  operator *  (const Integer& x, const Integer& y) 
  940. {
  941.   Integer r; mul(x, y, r); return r;
  942. }
  943.  
  944. inline Integer  operator *  (const Integer& x, long y) 
  945. {
  946.   Integer r; mul(x, y, r); return r;
  947. }
  948.  
  949. inline Integer  operator *  (long  x, const Integer& y) 
  950. {
  951.   Integer r; mul(x, y, r); return r;
  952. }
  953.  
  954. inline Integer sqr(const Integer& x) 
  955. {
  956.   Integer r; mul(x, x, r); return r;
  957. }
  958.  
  959. inline Integer  operator &  (const Integer& x, const Integer& y) 
  960. {
  961.   Integer r; and(x, y, r); return r;
  962. }
  963.  
  964. inline Integer  operator &  (const Integer& x, long y) 
  965. {
  966.   Integer r; and(x, y, r); return r;
  967. }
  968.  
  969. inline Integer  operator &  (long  x, const Integer& y) 
  970. {
  971.   Integer r; and(x, y, r); return r;
  972. }
  973.  
  974. inline Integer  operator |  (const Integer& x, const Integer& y) 
  975. {
  976.   Integer r; or(x, y, r); return r;
  977. }
  978.  
  979. inline Integer  operator |  (const Integer& x, long y) 
  980. {
  981.   Integer r; or(x, y, r); return r;
  982. }
  983.  
  984. inline Integer  operator |  (long  x, const Integer& y) 
  985. {
  986.   Integer r; or(x, y, r); return r;
  987. }
  988.  
  989. inline Integer  operator ^  (const Integer& x, const Integer& y) 
  990. {
  991.   Integer r; xor(x, y, r); return r;
  992. }
  993.  
  994. inline Integer  operator ^  (const Integer& x, long y) 
  995. {
  996.   Integer r; xor(x, y, r); return r;
  997. }
  998.  
  999. inline Integer  operator ^  (long  x, const Integer& y) 
  1000. {
  1001.   Integer r; xor(x, y, r); return r;
  1002. }
  1003.  
  1004. inline Integer  operator /  (const Integer& x, const Integer& y) 
  1005. {
  1006.   Integer r; div(x, y, r); return r;
  1007. }
  1008.  
  1009. inline Integer operator /  (const Integer& x, long y) 
  1010. {
  1011.   Integer r; div(x, y, r); return r;
  1012. }
  1013.  
  1014. inline Integer operator %  (const Integer& x, const Integer& y) 
  1015. {
  1016.   Integer r; mod(x, y, r); return r;
  1017. }
  1018.  
  1019. inline Integer operator %  (const Integer& x, long y) 
  1020. {
  1021.   Integer r; mod(x, y, r); return r;
  1022. }
  1023.  
  1024. inline Integer operator <<  (const Integer& x, const Integer& y) 
  1025. {
  1026.   Integer r; lshift(x, y, r); return r;
  1027. }
  1028.  
  1029. inline Integer operator <<  (const Integer& x, long y) 
  1030. {
  1031.   Integer r; lshift(x, y, r); return r;
  1032. }
  1033.  
  1034. inline Integer operator >>  (const Integer& x, const Integer& y) 
  1035. {
  1036.   Integer r; rshift(x, y, r); return r;
  1037. }
  1038.  
  1039. inline Integer operator >>  (const Integer& x, long y) 
  1040. {
  1041.   Integer r; rshift(x, y, r); return r;
  1042. }
  1043.  
  1044. inline Integer pow(const Integer& x, long y) 
  1045. {
  1046.   Integer r; pow(x, y, r); return r;
  1047. }
  1048.  
  1049. inline Integer Ipow(long x, long y) 
  1050. {
  1051.   Integer r(x); pow(r, y, r); return r;
  1052. }
  1053.  
  1054. inline Integer pow(const Integer& x, const Integer& y) 
  1055. {
  1056.   Integer r; pow(x, y, r); return r;
  1057. }
  1058.  
  1059.  
  1060.  
  1061. inline Integer abs(const Integer& x) 
  1062. {
  1063.   Integer r; abs(x, r); return r;
  1064. }
  1065.  
  1066. inline Integer operator - (const Integer& x) 
  1067. {
  1068.   Integer r; negate(x, r); return r;
  1069. }
  1070.  
  1071. inline Integer operator ~ (const Integer& x) 
  1072. {
  1073.   Integer r; complement(x, r); return r;
  1074. }
  1075.  
  1076. inline Integer  atoI(const char* s, int base) 
  1077. {
  1078.   Integer r; r.rep = atoIntRep(s, base); return r;
  1079. }
  1080.  
  1081. inline Integer  gcd(const Integer& x, const Integer& y) 
  1082. {
  1083.   Integer r; r.rep = gcd(x.rep, y.rep); return r;
  1084. }
  1085.  
  1086. #endif  /* NO_NRV */
  1087.  
  1088. inline void Integer::operator %= (const Integer& y)
  1089. {
  1090.   *this = *this % y; // mod(*this, y, *this) doesn't work.
  1091. }
  1092.  
  1093. inline void Integer::operator %= (long y)
  1094. {
  1095.   *this = *this % y; // mod(*this, y, *this) doesn't work.
  1096. }
  1097. #endif /* !_Integer_h */
  1098.